package com.authine.cloudpivot.ext.controller.fun;

import cn.hutool.core.lang.Assert;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 *  职能职责表 二级
 **/
@RestController
@RequestMapping("/public/funTwoLevel")
@Slf4j
public class FunTwoLevelController extends BaseController {


    @Autowired
    CloudSqlService sqlService;

    /**
     *  职能职责表 二级  审批流完成后 数据写到-职能职责表 二级 基础
     */
    @RequestMapping("finish")
    public void finish(String bizId){
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.funTwoLevelAdd, bizId);

        List<Map<String,Object>> list = (List<Map<String, Object>>) bizObject.get("funTwoLevelDetail");

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //获取审批人

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        for (Map<String, Object> map : list) {
            String oneLevelCode = (String) map.get("oneLevelCode");
            String twoLevelCode = (String) map.get("twoLevelCode");
            String funCode = (String) map.get("funCode");

            try {
                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //判断是否已存在
                String id = existsBizObject(map);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.funTwoLevelBase, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("基础表-公司级档案操作成功 ");
                //调用存储过程
                callProcess(id);

            } catch (Exception e) {
                log.info("基础表-总公司档案操作失败 oneLevelCode={}, twoLevelCode={}, funCode={}",oneLevelCode ,twoLevelCode,funCode);
                log.info(e.getMessage(), e);
            }

        }
    }



    /**
     *  作废职能职责表 二级  审批流完成后 数据写到-职能职责表 二级 基础
     */
    @RequestMapping("toVoid")
    public void toVoid(String bizId){
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.toVoidFunTwoLevel, bizId);

        List<Map<String,Object>> list = (List<Map<String, Object>>) bizObject.get("voidFunTwoLevelDetail");

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //获取审批人

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        for (Map<String, Object> map : list) {
            String oneLevelCode = (String) map.get("oneLevelCode");
            String twoLevelCode = (String) map.get("twoLevelCode");
            String funCode = (String) map.get("funCode");


            try {
                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //判断是否已存在
                String id = existsBizObject(map);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.funTwoLevelBase, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());//作废
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("基础表-二级职能作废操作成功 ");
                //调用存储过程
                callProcessToVoid(id);

            } catch (Exception e) {
                log.info("基础表-二级职能作废操作失败 oneLevelCode={}, twoLevelCode={}, funCode={}",oneLevelCode ,twoLevelCode,funCode);
                log.info(e.getMessage(), e);
            }

        }
    }

    /**
     *  调用存储过程
     *  exec  SyncRespBaseTwo
     * FunCode nvarchar(50),        ---- 职能代码  01
     * OneNumber nvarchar(50),        ---- 一级职责代码    01
     * Number nvarchar(50),        ---- 二级职责代码   01
     * Name nvarchar(200),        ---- 二级职责名称
     * Desc nvarchar(500),        ---- 职责描述
     * Auditor nvarchar(100)        ---- 审批人员工代码+空格+姓名
     * @param bizId
     */
    private void callProcess(String bizId){

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.funTwoLevelBase);
        StringBuilder sql = new StringBuilder("SELECT funCode,oneLevelCode,twoLevelCode,twoLevelDuty,funDesc,auditer from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}",map);

        //调用存储过程

        String funCode = MapUtils.getString(map,"funCode","");
        String oneLevelCode = MapUtils.getString(map,"oneLevelCode","");
        String twoLevelCode = MapUtils.getString(map,"twoLevelCode","");
        String twoLevelDuty = MapUtils.getString(map,"twoLevelDuty","");
        String funDesc = MapUtils.getString(map,"funDesc","");
        String auditer = MapUtils.getString(map,"auditer","");

        Assert.isFalse(StringUtils.isEmpty(funCode),"{}不能为空","funCode");
        Assert.isFalse(StringUtils.isEmpty(oneLevelCode),"{}不能为空","oneLevelCode");
        Assert.isFalse(StringUtils.isEmpty(twoLevelCode),"{}不能为空","twoLevelCode");
        Assert.isFalse(StringUtils.isEmpty(twoLevelDuty),"{}不能为空","twoLevelDuty");
        Assert.isFalse(StringUtils.isEmpty(funDesc),"{}不能为空","funDesc");
        Assert.isFalse(StringUtils.isEmpty(auditer),"{}不能为空","auditer");

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncRespBaseTwo '%s','%s','%s','%s','%s','%s'",
                funCode,oneLevelCode,twoLevelCode,twoLevelDuty,funDesc,auditer );

        log.info("\n==========准备调用存储过程:{}",execSql);

        sqlService.execute(CloudSqlService.htEas,execSql);

        log.info("\n=============存储过程执行完成");

    }

    /**
     *  调用存储过程
     *exec  RespBaseTwoVoid
 *        FunCode   nvarchar(100),			----职能代码
     *    NumberOne  nvarchar(100),			----一级代码
     *    NumberTwo  nvarchar(100),			----二级代码
     *    Auditor  nvarchar(50)				----审批人员工代码+空格+姓名
     */
    private void callProcessToVoid(String bizId){

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.funTwoLevelBase);
        StringBuilder sql = new StringBuilder("SELECT funCode,oneLevelCode,twoLevelCode,twoLevelDuty,funDesc,auditer from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}",map);

        //调用存储过程

        String funCode = MapUtils.getString(map,"funCode","");
        String oneLevelCode = MapUtils.getString(map,"oneLevelCode","");
        String twoLevelCode = MapUtils.getString(map,"twoLevelCode","");
        String auditer = MapUtils.getString(map,"auditer","");

        Assert.isFalse(StringUtils.isEmpty(funCode),"{}不能为空","funCode");
        Assert.isFalse(StringUtils.isEmpty(oneLevelCode),"{}不能为空","oneLevelCode");
        Assert.isFalse(StringUtils.isEmpty(twoLevelCode),"{}不能为空","twoLevelCode");
        Assert.isFalse(StringUtils.isEmpty(auditer),"{}不能为空","auditer");

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].RespBaseTwoVoid '%s','%s','%s','%s'",
                funCode,oneLevelCode,twoLevelCode,auditer );

        log.info("\n==========准备调用作废存储过程:{}",execSql);

        sqlService.execute(CloudSqlService.htEas,execSql);

        log.info("\n=============作废存储过程执行完成");

    }
    /**
     *  查询审批人,返回  员工号+姓名
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {


        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity7";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append(" ").append(user.getName()).toString();
    }



    /**
     * 判断是否已存在
     * @return
     */
    private String existsBizObject(Map<String,Object> data){

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.funTwoLevelBase);
        String oneLevelCode = (String) data.get("oneLevelCode");
        String twoLevelCode = (String) data.get("twoLevelCode");
        String funCode = (String) data.get("funCode");

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName)
                .append(" where oneLevelCode='").append(oneLevelCode)
                .append("' and twoLevelCode='").append(twoLevelCode)
                .append("' and funCode='").append(funCode).append("';");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     *  转换成  基础表-总公司档案 的数据
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String,Object> fileInfoBaseMap(Map<String,Object> map,String auditDate,String auditer){
        Map<String, Object> data = new HashMap<>();

        //审批时间
        data.put("auditDate",map.get("auditDate"));
        //审批人
        data.put("auditer",map.get("auditer"));
        //职能代码隐藏
        data.put("funCode",map.get("funCode"));
        //职能总责部门代码隐藏
        data.put("funDutyDeptCode",map.get("funDutyDeptCode"));
        //职能总责部门
        data.put("funDutyDeptName",map.get("funDutyDeptName"));
        //职能
        data.put("funName",map.get("funName"));
        //一级代码
        data.put("oneLevelCode",map.get("oneLevelCode"));
        //一级职责
        data.put("oneLevelDuty",map.get("oneLevelDuty"));
        //职能代码
        data.put("relevFun",map.get("relevFun"));
        //职能总责部门代码
        data.put("relevFunDutyDept",map.get("relevFunDutyDept"));
        //二级代码
        data.put("twoLevelCode",map.get("twoLevelCode"));
        //二级职责
        data.put("twoLevelDuty",map.get("twoLevelDuty"));
        //职责描述
        data.put("funDesc",map.get("funDesc"));



        //审批时间
        data.put("auditDate",auditDate);
        //审批人
        data.put("auditer",auditer);

        return data;
    }
}
